#ifndef xpack_lang_cxx_format
#define xpack_lang_cxx_format
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::lang_cxx::inc
#include"define/base_type.hpp"
#include"interface/can_alloc.hpp"
#include"interface/ranger.hpp"

// private/ 放前面
#include"lang/cxx/private/format_base.hpp"
#include"lang/cxx/count_of.hpp"
#include"lang/cxx.hpp"
#include"macro/xoffsetof.hpp"
#include"macro/xunlikely.hpp"
#include"math/literal.hpp"
#include"math/numeration_t.hpp"
#include"memop/copy.hpp"
#include"meta/is_based_on.hpp"
#include"meta/is_float.hpp"
#include"meta/is_integer.hpp"
#include"meta/is_origin_string.hpp"
#include"meta/item_origin_of.hpp"
#include"meta/origin_of.hpp"
#include"meta/prop_type.hpp"
#include"meta/remove_const.hpp"
#include"meta/is_xstruct_prop.hpp"
#include"utils/mix_buffer.hpp"
#include"utils/mix_item.hpp"
#pragma pop_macro("xuser")

namespace mixc::lang_cxx{
    namespace inc{
        using namespace literal;
    }

    /*
     * h{}  hex
     * H{}  upper hex 
     * zh{} hex with leading zero
     * zH{} upper hex with leading zero
     * x{}  hex with 0x prefix
     * X{}  upper hex with 0x prefix
     * zx{} hex with 0x prefix and leading zero
     * zX{} upper hex with 0x prefix and leading zero
     * o{}  oct
     * zo{} oct with leading zero
     * b{}  bin
     * zb{} bin with leading zero
     * 
     * vl{} value list
     * f{}  decimal
     * 
     * .l() align left
     * .r() align right
     * .c() align center
     * 
     * more... to be continue
     */

    constexpr auto place_holder_char = '\v';

    enum align_mode_t{
        align_left,
        align_center,
        align_right,
    };

    enum hex_mode_t{
        with_0x_prefix      = 1,
        with_h_suffix       = 2,
        keep_leading_zero   = 4,
        upper_hex           = 8,
    };


    template<class final_t>
    struct format_wrapper : protected inc::format_base {
        using the_t = format_wrapper<final_t>;
        using inc::format_base::format_base;

        final_t & c(uxx align_center_width, char left_padding_char, char right_padding_char) const {
            m_align_mode                = u08(align_center);
            m_align_width               = u16(align_center_width);
            m_left_padding_char         = left_padding_char;
            m_right_padding_char        = right_padding_char;
            return xthex;
        }

        final_t & c(uxx align_center_width, char padding_char = ' ') const {
            return c(align_center_width, padding_char, padding_char);
        }

        final_t & l(uxx align_left_width, char padding_char = ' ') const {
            m_align_mode                = u08(align_left);
            m_align_width               = u16(align_left_width);
            m_right_padding_char        = padding_char;
            return xthex;
        }

        final_t & r(uxx align_right_width, char padding_char = ' ') const {
            m_align_mode                = u08(align_right);
            m_align_width               = u16(align_right_width);
            m_left_padding_char         = padding_char;
            return xthex;
        }

        final_t & align_adjust(bool value) const {
            m_align_adjust              = value;
            return xthex;
        }
    };

    template<class char_t>
    inline void align_wrapper(
        inc::format_base          * base, 
        auto                const & alloc,
        auto                const & inovke
    ){
        auto stream                 = decltype(alloc(0)){};
        auto pad_width              = uxx{};
        auto wrapper                = [&](uxx length){
            auto real_length        = length;
            pad_width               = base->m_align_width - length;

            if (base->m_align_width <= length){
                return alloc(length);
            }
            else{
                stream              = alloc(real_length = base->m_align_width);
            }

            xunlikely(stream == nullptr){
                return stream;
            }

            switch(base->m_align_mode){
            case align_right:
                stream.output(base->m_left_padding_char, pad_width);
                return stream;
            case align_center:
                stream.output(base->m_left_padding_char, pad_width / 2);
                pad_width          -= pad_width / 2;
                return stream;
            default: // case align_left:
                return stream;
            }
        };

        if (inovke(wrapper); stream == nullptr){
            return;
        }

        if (base->m_align_mode == align_center){
            stream.output(base->m_right_padding_char, pad_width);
        }
        else if (base->m_align_mode == align_left){
            stream.output(base->m_right_padding_char, pad_width);
        }
    }

    template<class char_t>
    inline void align_adjust(inc::format_base * base, inc::cxx<char_t> value){
        auto ascii_count        = value.count_of(inc::expect_ascii<char_t>);
        auto unicode_count      = value.count_of(inc::expect_unicode<char_t>);
        auto length             = uxx(value->length);
        auto remainder          = uxx{};

        if constexpr (sizeof(char_t) == 1){
            remainder           = length - ascii_count - unicode_count * 2/*两倍 ascii 字符宽度*/;
        }
        else{
            remainder           = ascii_count + unicode_count * 2/*两倍 ascii 字符宽度*/ - length;
        }

        base->m_align_width    += u16(remainder);
    }

    template<class char_t>
    inline void to_hex(const void * mem, uxx bytes, asciis lut, bool with_0x_prefix, auto const & alloc){
        // 未考虑大端模式
        char_t buf[2]           = { '0', 'x' };
        auto length             = uxx{};
        auto ptr                = u08p(mem) + bytes;
        auto stream             = decltype(alloc(0)){};
        auto ignore             = true;
        auto set_prefix         = [&](){
            if (with_0x_prefix){
                stream.output(buf, 2);
            }
        };

        while(bytes-- > 0){
            // 忽略前导 0
            if (ptr -= 1; ptr[0] == 0 and ignore){
                continue;
            }

            if (ignore == false){
                buf[0]          = lut[ptr[0] >> 4];
                buf[1]          = lut[ptr[0] & 0xf];
                stream.output(buf, 2);
                continue;
            }

            if (ignore = false; *ptr & 0xf0){
                length          = 2 * (bytes + 1);
                stream          = alloc(length);

                xunlikely(stream == nullptr){
                    return;
                }

                set_prefix();
                buf[0]          = lut[ptr[0] >> 4];
                buf[1]          = lut[ptr[0] & 0xf];
                stream.output(buf, 2);
            }
            else{
                length          = 2 * (bytes + 1) - 1;
                stream          = alloc(length);

                xunlikely(stream == nullptr){
                    return;
                }

                set_prefix();
                buf[0]          = lut[ptr[0] & 0xf];
                stream.output(buf, 1);
            }
        }

        if (stream == nullptr){
            length              = 1;
            stream              = alloc(length);

            if (stream != nullptr){
                set_prefix();
                stream.output(lut[0]);
            }
        }
    }

    template<class char_t>
    inline void to_hex_keep_leading_zero(const void * mem, uxx bytes, asciis lut, bool with_0x_prefix, auto const & alloc){
        // 未考虑大端模式
        char_t buf[2] = { '0', 'x' };
        auto length             = bytes * 2;
        auto stream             = alloc(length);
        auto ptr                = u08p(mem) + bytes;

        xunlikely(stream == nullptr){
            return;
        }

        if (with_0x_prefix){
            stream.output(buf, 2);
        }

        while(bytes-- > 0){
            ptr                -= 1;
            buf[0]              = lut[ptr[0] >> 4];
            buf[1]              = lut[ptr[0] & 0xf];
            stream.output(buf, 2);
        }
    }

    template<class float_t, class char_t>
    inline void float_format(inc::format_base * base, auto const & alloc){
        align_wrapper<char_t>(base, alloc, [&](auto const & wrapper){
            if (base->m_numeration != base->empty_numeration){
                inc::cxx<char_t>(
                    base->template get<float_t>(),
                    inc::float_format_t(base->m_mode),
                    base->m_numeration, // 精度
                    wrapper
                );
            }
            else{
                inc::cxx<char_t>(
                    base->template get<float_t>(),
                    inc::float_format_t(base->m_mode),
                    wrapper
                );
            }
        });
    }

    #define __xgen_format(TYPE)                                                         \
        auto result = inc::cxx<TYPE>{};                                                 \
        auto allocx = inc::cxx<TYPE>::helper::stream_helper(alloc, xmodify(result));

    #define xgen_format(...)                                                            \
        inc::c08 format(inc::ialloc<char> const & alloc){                               \
            __xgen_format(char)                                                         \
            __format_core<char>(allocx);                                                \
            return result;                                                              \
        }                                                                               \
                                                                                        \
        inc::c16 format(inc::ialloc<char16_t> const & alloc){                           \
            __xgen_format(char16_t)                                                     \
            __format_core<char16_t>(allocx);                                            \
            return result;                                                              \
        }                                                                               \
                                                                                        \
        void format(inc::stream_wrapperx<char> const & alloc){                          \
            __xgen_format(char)                                                         \
            __format_core<char>(allocx);                                                \
        }                                                                               \
                                                                                        \
        void format(inc::stream_wrapperx<char16_t> const & alloc){                      \
            __xgen_format(char16_t)                                                     \
            __format_core<char16_t>(allocx);                                            \
        }                                                                               \
                                                                                        \
        void format(inc::cxx_helper<char>::__batches_lambda const & alloc){             \
            __xgen_format(char)                                                         \
            __format_core<char>(allocx);                                                \
        }                                                                               \
                                                                                        \
        void format(inc::cxx_helper<char16_t>::__batches_lambda const & alloc){         \
            __xgen_format(char16_t)                                                     \
            __format_core<char16_t>(allocx);                                            \
        }
    
    #define xgen_formatx(...)                                                           \
        inc::c08 format(inc::c08 const & fmt, inc::ialloc<char> const & alloc){         \
            __xgen_format(char)                                                         \
            __format_core<char>(fmt, allocx);                                           \
            return result;                                                              \
        }                                                                               \
                                                                                        \
        inc::c16 format(inc::c08 const & fmt, inc::ialloc<char16_t> const & alloc){     \
            __xgen_format(char16_t)                                                     \
            __format_core<char16_t>(fmt, allocx);                                       \
            return result;                                                              \
        }                                                                               \
                                                                                        \
        void format(inc::c08 const & fmt, inc::stream_wrapperx<char> const & alloc){    \
            __xgen_format(char)                                                         \
            __format_core<char>(fmt, allocx);                                           \
        }                                                                               \
                                                                                        \
        void format(inc::c08 const & fmt, inc::stream_wrapperx<char16_t> const & alloc){\
            __xgen_format(char16_t)                                                     \
            __format_core<char16_t>(fmt, allocx);                                       \
        }                                                                               \
                                                                                        \
        void format(                                                                    \
            inc::c08 const & fmt,                                                       \
            inc::cxx_helper<char>::__batches_lambda const & alloc){                     \
            __xgen_format(char)                                                         \
            __format_core<char>(fmt, allocx);                                           \
        }                                                                               \
                                                                                        \
        void format(                                                                    \
            inc::c08 const & fmt,                                                       \
            inc::cxx_helper<char16_t>::__batches_lambda const & alloc){                 \
            __xgen_format(char16_t)                                                     \
            __format_core<char16_t>(fmt, allocx);                                       \
        }

    template<class final_t, class item_t>
    struct h_base : format_wrapper<final_t>{
        using the_t     = h_base<final_t, item_t>;
        using itemp_t   = item_t *;
        using format_wrapper<final_t>::format_wrapper;

    protected:
        void mode(uxx value){
            inc::format_base::m_mode= u08(value);
        }

        xgen_format()

        template<class char_t>
        void __format_core(auto const & alloc){
            auto stream             = decltype(alloc(0)){};
            auto lambda_addition    = [&](uxx length){
                if (inc::format_base::m_mode & hex_mode_t::with_0x_prefix){
                    stream          = alloc(length + 2);
                    return stream;
                }
                else if (inc::format_base::m_mode & hex_mode_t::with_h_suffix){
                    // stream[length]     = 'h'; 放到后面上设置 -> stream.output(&h, 1);
                    return stream = alloc(length + 1);
                }
                else{
                    return stream = alloc(length);
                }
            };

            // wrapper -> lambda_addition -> alloc
            align_wrapper<char_t>(this, lambda_addition, [&](auto const & wrapper){
                auto lut            = inc::format_base::m_mode & hex_mode_t::upper_hex ? inc::upper : inc::lower;
                auto bytes          = sizeof(item_t);
                auto func           = [&](const void * mem, uxx bytes, asciis lut){
                    auto prefix_0x  = (inc::format_base::m_mode & hex_mode_t::with_0x_prefix) != 0;
                    if (inc::format_base::m_mode & hex_mode_t::keep_leading_zero){
                        to_hex_keep_leading_zero<char_t>(mem, bytes, lut, prefix_0x, wrapper);
                    }
                    else{
                        to_hex<char_t>(mem, bytes, lut, prefix_0x, wrapper);
                    }
                };

                if constexpr (inc::is_cxx<item_t> or inc::is_origin_string<item_t>){
                    auto & v        = this->template get<item_t>();
                    auto value      = inc::cxx<inc::item_origin_of<item_t>>(v);
                    bytes           = sizeof(value[0]) * value->length;

                    if (bytes == 0){ // 至少要有一位数据，即使是空字符串
                        bytes       = sizeof(value[0]);
                    }
                    func(& value[0], bytes, lut);
                }
                else{
                    auto & value    = this->template get<item_t>();
                    func(& value, bytes, lut);
                }

                if (inc::format_base::m_mode & hex_mode_t::with_h_suffix){
                    xunlikely(stream == nullptr){
                        return;
                    }
                    stream.output('h');
                }
            });
        }
    };
}

namespace mixc::lang_cxx::origin::place_holder{
    template<class prop_t, class item_t = inc::prop_type<prop_t, with_propcast>>
    struct v : format_wrapper<v<prop_t>>{
        using the_t                 = v<prop_t>;
        using base_t                = format_wrapper<v<prop_t>>;

        constexpr v(prop_t && value) :
            base_t(xoffsetof(the_t, m_value)), m_value(value){
        }

        constexpr v(prop_t & value) :
            base_t(xoffsetof(the_t, m_value)), m_value(value){
        }

        xgen_format()

        template<class char_t>
        void __format_core(auto const & alloc){
            if constexpr(inc::is_cxx<item_t> or inc::is_origin_string<item_t>){
                using item_char_t = inc::item_origin_of<item_t>;

                if (inc::format_base::m_align_adjust and inc::format_base::m_align_width != 0){
                    inc::format_base::m_align_adjust = false;
                    align_adjust<item_char_t>(this, m_value);
                }
            }

            align_wrapper<char_t>(this, alloc, [&](auto & wrapper){
                inc::cxx<char_t>(m_value, wrapper);
            });
        }
    protected:
        item_t m_value;
    };

    template<class item_t, uxx length_v>
    struct v<item_t[length_v]> : format_wrapper<v<item_t[length_v]>>{
        using base_t        = format_wrapper<v<item_t[length_v]>>;
        using the_t         = v<item_t[length_v]>;

        constexpr v(item_t const * value) :
            base_t(xoffsetof(the_t, m_value)), m_value(){
            inc::copy(m_value, value, length_v);
        }

        xgen_format()

        template<class char_t>
        void __format_core(auto const & alloc){
            if constexpr(inc::is_origin_string<item_t[length_v]>){
                if (inc::format_base::m_align_adjust and inc::format_base::m_align_width != 0){
                    inc::format_base::m_align_adjust = false;
                    using item_char_t = inc::remove_const<item_t>;
                    align_adjust<item_char_t>(this, m_value);
                }
            }

            align_wrapper<char_t>(this, alloc, [&](auto const & wrapper){
                inc::cxx<char_t>(m_value, wrapper);
            });
        }
    private:
        item_t m_value[length_v];
    };

    template<inc::is_integer item_t>
    struct v<item_t> : format_wrapper<v<item_t>>{
        using the_t     = v<item_t>;
        using itemp_t   = item_t *;

        constexpr v(item_t && value) :
            format_wrapper<the_t>(xoffsetof(the_t, m_value)), m_value(value){
            this->s(false);
            this->radix(10);
        }

        constexpr v(item_t & value) :
            format_wrapper<the_t>(xoffsetof(the_t, m_value)), m_value(value){
            this->s(false);
            this->radix(10);
        }

        the_t & s(bool value){
            inc::format_base::m_mode         = u08(value ? 
                inc::int_format_t::fmt_sn : 
                inc::int_format_t::fmt_n
            );

            return *this;
        }

        the_t & radix(uxx value){
            xunlikely(value < 2 or value > 64){
                return *this;
            }

            inc::format_base::m_numeration   = u16(value);
            return *this;
        }

        xgen_format()

        template<class char_t>
        void __format_core(auto const & alloc){
            align_wrapper<char_t>(this, alloc, [this](auto const & wrapper){
                inc::cxx<char_t>(
                    the_t::m_value,
                    inc::int_format_t(inc::format_base::m_mode),
                    inc::numeration_t(inc::format_base::m_numeration),
                    wrapper
                );
            });
        }
    private:
        item_t m_value;
    };

    #define xph_hex(name,...)                                   \
    template<class item_t>                                      \
    struct name : h_base<name<item_t>, item_t>{                 \
        using base_t    = h_base<name<item_t>, item_t>;         \
        using the_t     = name<item_t>;                         \
                                                                \
        constexpr name(item_t && value) :                       \
            base_t(xoffsetof(the_t, m_value)), m_value(value){  \
            this->mode(__VA_ARGS__);                            \
        }                                                       \
                                                                \
        constexpr name(item_t & value) :                        \
            base_t(xoffsetof(the_t, m_value)),                  \
            m_value(value){                                     \
            this->mode(__VA_ARGS__);                            \
        }                                                       \
                                                                \
        using base_t::format;                                   \
        using base_t::__format_core;                            \
    private:                                                    \
        item_t m_value;                                         \
    };                                                          \
                                                                \
    template<class item_t, uxx length_v>                        \
    struct name<item_t[length_v]> :                             \
        h_base<name<item_t[length_v]>, item_t[length_v]>{       \
                                                                \
        using base_t = h_base<                                  \
            name<item_t[length_v]>,                             \
            item_t[length_v]                                    \
        >;                                                      \
        using the_t = name<item_t[length_v]>;                   \
        using base_t::format;                                   \
        using base_t::__format_core;                            \
                                                                \
        name(item_t const * value) :                            \
            base_t(xoffsetof(the_t, m_value)), m_value(){       \
            inc::copy(m_value, value, length_v);                \
            this->mode(__VA_ARGS__);                            \
        }                                                       \
    private:                                                    \
        item_t m_value[length_v];                               \
    };                                                          \
                                                                \
    template<inc::is_xstruct_prop prop_t>                       \
    struct name<prop_t> :                                       \
        name<inc::prop_type<prop_t, with_propcast>>{            \
        constexpr name(prop_t const & prop) : name<             \
            inc::prop_type<prop_t, with_propcast>               \
        >(prop()){}                                             \
    }


    xph_hex(h,         0);
    xph_hex(zh,        hex_mode_t::keep_leading_zero);
    xph_hex(H,         hex_mode_t::upper_hex);
    xph_hex(zH,        hex_mode_t::keep_leading_zero | hex_mode_t::upper_hex);
    
    xph_hex(hs,        hex_mode_t::with_h_suffix);
    xph_hex(zhs,       hex_mode_t::with_h_suffix | hex_mode_t::keep_leading_zero);
    xph_hex(Hs,        hex_mode_t::with_h_suffix | hex_mode_t::upper_hex);
    xph_hex(zHs,       hex_mode_t::with_h_suffix | hex_mode_t::keep_leading_zero | hex_mode_t::upper_hex);

    xph_hex(x,         hex_mode_t::with_0x_prefix);
    xph_hex(zx,        hex_mode_t::with_0x_prefix | hex_mode_t::keep_leading_zero);
    xph_hex(X,         hex_mode_t::with_0x_prefix | hex_mode_t::upper_hex);
    xph_hex(zX,        hex_mode_t::with_0x_prefix | hex_mode_t::keep_leading_zero | hex_mode_t::upper_hex);

    
    #define xph_float(name,...)                                         \
    template<                                                           \
        class prop_t,                                                   \
        class float_t = inc::origin_of<prop_t, with_propcast>           \
    >                                                                   \
    requires(inc::is_float<float_t>)                                    \
    struct name : format_wrapper<name<prop_t>>{                         \
        using the_t                     = name<prop_t>;                 \
        using itemp_t                   = float_t *;                    \
                                                                        \
        name(prop_t const & value) :                                    \
            format_wrapper<the_t>(xoffsetof(the_t, m_value)),           \
            m_value(value){                                             \
            this->precious(inc::format_base::empty_numeration);         \
            this->mode(__VA_ARGS__);                                    \
        }                                                               \
                                                                        \
        the_t & mode(inc::float_format_t value){                        \
            inc::format_base::m_mode             = u16(value);          \
            return *this;                                               \
        }                                                               \
                                                                        \
        the_t & precious(uxx value){                                    \
            inc::format_base::m_numeration       = u16(value);          \
            return *this;                                               \
        }                                                               \
                                                                        \
        xgen_format()                                                   \
                                                                        \
        template<class char_t>                                          \
        void __format_core(auto const & alloc){                         \
            float_format<float_t, char_t>(this, alloc);                 \
        }                                                               \
    private:                                                            \
        float_t m_value;                                                \
    }

    xph_float(f, inc::float_format_t::fmt_n);
    xph_float(e, inc::float_format_t::fmt_1p2e3);

    #undef  xph_hex
    #undef  xph_float
}

namespace mixc::lang_cxx{
    template<class ... args_t>
    struct vl_core;

    template<class first_t, class ... args_t>
    struct vl_core<first_t, args_t...> : vl_core<args_t...>{
        using base_t            = vl_core<args_t...>;
        using basep_t           = base_t *;

        constexpr vl_core(first_t first, args_t ... rest):
            base_t(rest...), value(first){
        }

        template<class char_t>
        void __format_core(auto const & prev){
            auto link               = [&](uxx sub_length){
                auto stream         = decltype(prev(0)){}; 
                auto alloc          = [&](uxx this_length){
                    stream          = prev(this_length + sub_length);
                    return stream;
                };

                if constexpr (inc::is_based_on<inc::format_base, first_t>){
                    value.template __format_core<char_t>(alloc);
                }
                else{
                    origin::place_holder::v val{ value };
                    val.template __format_core<char_t>(alloc);
                }
                return stream;
            };

            base_t::template __format_core<char_t>(link);
        }
    
        template<class char_t>
        void __format_core(
            inc::cxx<char_t>    const & fmt, 
            auto                const & alloc,
            auto                const & ... args){
            base_t::template __format_core<char_t>(fmt, alloc, args..., value);
        }

    private:
        first_t value;
    };

    template<>
    struct vl_core<>{
        constexpr vl_core(){}
        
        template<class char_t>
        void __format_core(auto const & emit){
            // 从这里开始正式执行
            emit(0);
        }

        template<class char_t>
        void __format_core(
            inc::cxx<char_t>    const & fmt, 
            auto                const & alloc, 
            auto                const & ... args){
            fmt.format(args..., alloc);
        }
    };
}

namespace mixc::lang_cxx::origin::place_holder{
    template<class first_t, class ... args_t>
    struct vl :  
        format_wrapper<vl<first_t, args_t...>>,

        // NOTE:
        // vl{ "str..." }; 对于这种模板，自动识别的 first_t 类型为 char[7]
        // 但构造函数仍是 const char* 类型，如果需要识别成 char[7] 需要使用 first_t && 参数类型
        // 规则是:
        // first_t const & 识别成指针
        // first_t && 识别成原始数组，但实际上还是一个指针
        // vl(char[7] first...) 这种类型在参数中是指针，但如果放在成员变量中则是真实的数组
        //
        // ::mixc::lang_cxx::vl_core<
        //     inc::prop_type<first_t, with_propcast>, 
        //     inc::prop_type<args_t, with_propcast>...
        // >{

        ::mixc::lang_cxx::vl_core<
            inc::prop_type<first_t const &, with_propcast>, 
            inc::prop_type<args_t const &, with_propcast>...
        >{

        using base_t                = ::mixc::lang_cxx::vl_core<
            inc::prop_type<first_t const &, with_propcast>, 
            inc::prop_type<args_t const &, with_propcast>...
        >;
        using basep_t               = base_t *;

        vl(first_t const & first, args_t const & ... rest):
            format_wrapper<vl<first_t, args_t...>>(0), base_t(first, rest...){
        }

        xgen_format()
        xgen_formatx()

        template<class char_t>
        void __format_core(auto const & alloc){
            align_wrapper<char_t>(this, alloc, /*invoke*/[&](auto const & wrapper){
                auto self = (base_t *)this; // 兼容 g++12.3 这样写一定没错，只是不简洁
                self->template __format_core<char_t>(wrapper);
            });
        }

        template<class char_t>
        void __format_core(inc::cxx<char_t> const & fmt, auto const & alloc){
            base_t::template __format_core<char_t>(fmt, alloc);
        }
    };
}

namespace mixc::lang_cxx{
    template<class item_t>
    inline void formatx(auto fmt, auto const & list, auto & stream){
        auto j              = uxx{};

        for(uxx i = 0, length = fmt->length; i < length; i++){
            if (fmt[i] != place_holder_char){
                auto c      = fmt[i];
                stream.output(&c, 1);
                continue;
            }
            else if (j < list->length){
                list[j++].format(stream);
            }
            else{
                item_t v[]  = { '\\', 'v' };
                stream.output(v, 2);
            }
        }

        // 如果还有剩余的占位符元素，就追加到末尾
        while(j < list->length){
            list[j++].format(stream);
        }
    }

    template<class item_t>
    template<class xalloc_t, class ret_t, class>
    inline ret_t cxx<item_t>::format_core(bool is_secret, inc::ranger<mix_item> const & list, xalloc_t const & alloc) const {
        constexpr
        auto is_stream          = the_t::helper::template can_stream<xalloc_t>;
        auto old                = *inner::l_is_secret;  // 先
        *inner::l_is_secret     = is_secret;            // 后，需要单独设置，因为 format() 可能在 alloc 中产生嵌套
        auto result             = the_t{};
        auto allocx             = the_t::helper::stream_helper(alloc, xmodify(result.m_ptr), xmodify(result.m_length));
        the_t::helper::template in_batches<is_stream>(allocx, [&](auto & stream){
            formatx<item_t>(xthe, list, stream);
        });

        *inner::l_is_secret     = old;

        if constexpr (inc::is_same<ret_t, the_t>){
            return result;
        }
    }

    #undef  xgen_format
    #undef  xgen_formatx
}

#endif

xexport_space(mixc::lang_cxx::origin::place_holder)
xexport_space(mixc::lang_cxx::origin)
xexport(mixc::lang_cxx::inc::float_format_t)
xexport(mixc::lang_cxx::inc::int_format_t)
xexport(mixc::lang_cxx::inc::numeration_t)
